<template>
  <div :class="[formOptionState.card ? 'a-form-card' : 'a-form']">
    <el-form
      ref="ruleFormRefState"
      :model="ruleFormState"
      :rules="formOptionRules"
      class="demo-form-inline"
      :validate-on-rule-change="false"
      :label-width="
        formOptionState.formLabelWidth ? formOptionState.formLabelWidth : 80
      "
      :label-position="
        formOptionState.formLabelPosition
          ? formOptionState.formLabelPosition
          : 'right'
      "
    >
      <el-row :gutter="20">
        <template
          v-for="(item, index) in formOptionState.columns"
          :key="item.prop"
        >
          <el-col
            :style="{
              display:
                !item.display || item.display == 'block' ? 'block' : 'none',
            }"
            :span="item.row ? 24 : formOptionState.labelWidthSpan || 8"
            :xs="24"
            :sm="item.row ? 24 : 12"
            :md="item.row ? 24 : formOptionState.labelWidthSpan || 8"
            :lg="item.row ? 24 : formOptionState.labelWidthSpan || 8"
            :xl="item.row ? 24 : formOptionState.labelWidthSpan || 8"
          >
            <el-form-item
              :label="item.labelSlot ? '' : item.label"
              :prop="item.prop"
              :class="[item.labelSlot ? 'el-form-item-slot' : '']"
            >
              <!-- 自定义名称插槽 -->
              <template #label v-if="item.labelSlot">
                <slot v-if="item.labelSlot" :name="item.prop + 'Label'"></slot>
              </template>

              <!-- 输入框 -->
              <el-input
                v-if="!item.formSlot && (!item.type || item.type == 'input')"
                v-model="ruleFormState[item.prop]"
                :placeholder="
                  item.placeholder ? item.placeholder : `请输入${item.label}`
                "
                :clearable="
                  !item.clearable && item.clearable == false ? false : true
                "
                :disabled="item.disabled || false"
                :readonly="item.readonly || false"
                :show-word-limit="item.showWordLimit"
                :maxlength="item.maxlength"
                style="width: 100% !important"
              />
              <!-- 文本框 -->
              <el-input
                v-if="
                  !item.formSlot &&
                  (item.type == 'textarea' || item.type == 'text')
                "
                v-model="ruleFormState[item.prop]"
                :placeholder="
                  item.placeholder ? item.placeholder : `请输入${item.label}`
                "
                :clearable="
                  !item.clearable && item.clearable == false ? false : true
                "
                :disabled="item.disabled || false"
                :readonly="item.readonly || false"
                :type="item.type"
                :show-word-limit="item.showWordLimit"
                :maxlength="item.maxlength"
                :rows="item.type == 'textarea' ? item.rows : 0"
                style="width: 100% !important"
              />
              <!-- 数字输入框 -->
              <el-input-number
                v-if="!item.formSlot && item.type == 'number'"
                v-model="ruleFormState[item.prop]"
                :min="item.min"
                :max="item.max"
                :disabled="item.disabled || false"
                :readonly="item.readonly || false"
                style="width: 100% !important"
              />
              <!-- 下拉框 -->
              <el-select
                v-if="!item.formSlot && item.type == 'select'"
                v-model="ruleFormState[item.prop]"
                :placeholder="
                  item.placeholder ? item.placeholder : `请选择${item.label}`
                "
                :clearable="
                  !item.clearable && item.clearable == false ? false : true
                "
                :filterable="item.filterable || false"
                :multiple="item.multiple || false"
                :disabled="item.disabled || false"
                :readonly="item.readonly || false"
                style="width: 100% !important"
              >
                <el-option
                  v-for="dic in item.dicData"
                  :key="dic.value"
                  :label="dic.label"
                  :value="dic.value"
                />
              </el-select>
              <!-- 下拉树形框 -->
              <el-tree-select
                v-if="!item.formSlot && item.type == 'treeSelect'"
                v-model="ruleFormState[item.prop]"
                :data="item.dicData"
                :filterable="item.filterable || false"
                :multiple="item.multiple || false"
                :show-checkbox="item.showCheckbox || false"
                style="width: 100% !important"
              />
              <!-- 单选框 -->
              <el-radio-group
                v-if="!item.formSlot && item.type == 'radio'"
                v-model="ruleFormState[item.prop]"
                :disabled="item.disabled || false"
              >
                <el-radio
                  v-for="dic in item.dicData"
                  :key="dic.value"
                  :label="dic.label"
                  :value="dic.value"
                ></el-radio>
              </el-radio-group>
              <!-- switch 开关 -->
              <el-switch
                v-if="!item.formSlot && item.type == 'switch'"
                v-model="ruleFormState[item.prop]"
                :size="item.size || 'small'"
                :active-text="item.activeText"
                :inactive-text="item.inactiveText"
                :disabled="item.disabled || false"
              />
              <!-- 日期选择器 -->
              <el-date-picker
                v-if="
                  !item.formSlot &&
                  (item.type == 'date' ||
                    item.type == 'datetime' ||
                    item.type == 'datetimerange')
                "
                v-model="ruleFormState[item.prop]"
                :type="item.type"
                :placeholder="
                  item.placeholder ? item.placeholder : `请输入${item.label}`
                "
                :clearable="
                  !item.clearable && item.clearable == false ? false : true
                "
                :disabled="item.disabled || false"
                :readonly="item.readonly || false"
                :format="item.format"
                :value-format="item.valueFormat"
                :start-placeholder="item.startPlaceholder"
                :end-placeholder="item.endPlaceholder"
                style="width: 100% !important"
              />
              <slot
                :name="item.prop + 'Form'"
                :disabled="item.disabled"
                :readonly="item.readonly"
                v-if="item.formSlot"
              >
              </slot>
            </el-form-item>
          </el-col>
        </template>
        <el-col>
          <div
            class="btns"
            :style="{ 'text-align': formOptionState.menuPosition || 'left' }"
          >
            <slot name="menuForm"></slot>
            <el-button
              v-if="formOptionState.addBtn"
              type="primary"
              @click="onSubmit"
            >
              {{ $t("globalSetting.submitBtn") }}
            </el-button>
            <el-button v-if="formOptionState.resetBtn" @click="onRest">
              {{ $t("globalSetting.cancelBtn") }}
            </el-button>
          </div>
        </el-col>
      </el-row>
    </el-form>
  </div>
</template>

<script lang="ts" setup>
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const props = defineProps({
  modelValue: {
    type: Object,
    default: () => {},
  },
  formOption: {
    type: Object,
    default: () => {},
  },
  type: {
    type: String,
    default: "add",
  },
});
const { modelValue, formOption, type } = toRefs(props);
const emit = defineEmits();
const ruleFormRefState = ref();

// 计算双向绑定的值
const ruleFormState = computed({
  get() {
    // console.log('modelValue', modelValue.value)
    return modelValue.value;
  },
  set(value) {
    emit("update:modelValue", value);
  },
});

// 重新计算value
const formOptionState = computed(() => {
  let formData;
  if (type.value == "add") {
    formData = formOption.value.columns.filter(
      (item) => item.addDisplay !== false
    );
    formData = formData.map((item) => {
      return {
        ...item,
        disabled: item.addDisabled ? true : false,
        readonly: item.addDeadonly ? true : false,
      };
    });
  } else if (type.value == "edit") {
    formData = formOption.value.columns.filter(
      (item) => item.editDisplay !== false
    );
    formData = formData.map((item) => {
      return {
        ...item,
        disabled: item.editDisabled ? true : false,
        readonly: item.editReadonly ? true : false,
      };
    });
  } else {
    formData = formOption.value.columns.filter(
      (item) => item.viewDisplay !== false
    );
    formData = formData.map((item) => ({ disabled: true, ...item }));
  }

  // 循环判断是否有默认初始化选中的值
  formData.forEach((item) => {
    if (item.value) {
      ruleFormState.value[item.prop] =
        modelValue.value[item.prop] || item.value;
    }
  });
  let data = {
    ...formOption.value,
    columns: formData,
  };
  return data;
});

// 重新计算rules
const formOptionRules = computed(() => {
  if (type.value == "add" || type.value == "edit") {
    let data = {};
    formOption.value.columns.forEach((item) => {
      if (item.rules && item.rules.length) {
        data[item.prop] = item.rules;
      }
    });

    return data;
  }
});

// 获取表单值的方法
function onSubmit() {
  ruleFormRefState.value.validate((valid, fields) => {
    if (valid) {
      // console.log("submit!");
      emit("onSubmit");
    } else {
      // console.log("error submit!", fields);
    }
  });
}

// 重置表单值的方法
function onRest() {
  emit("onRest");
}

defineExpose({
  ruleFormRefState,
  onSubmit,
  onRest,
});
</script>

<style lang="scss" scoped>
.a-form {
  .btns {
    // padding: 0 100px;
    margin-bottom: 18px;
  }
}

.a-form-card {
  padding: 18px 18px 0 18px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.3);
  .btns {
    padding: 0 100px;
    margin-bottom: 18px;
  }
}

:deep(.el-form-item-slot) {
  .el-form-item__label::before {
    content: "" !important;
    margin: 0 !important;
    height: 0 !important;
  }
}
</style>